/*************************************************************************
	> File Name: acquisition.c
	> Author: xuwenlong
	> Mail: myxuan475@126.com 
	> Created Time: 2018年01月17日 星期三 13时43分36秒
 ************************************************************************/
#include "acquisition.h"
#include <stdio.h>
#include <json/json.h>
#include <utils/logger.h>
#include <transport/globalmsg.h>
#include <utils/socket_request.h>
#include <md5cpp/md5.h>
#include <utils/config.h>
#include <devices/devices.h>
#include <dbms/models.h>
#include <dbms/acquire.h>
#include "channel.h"
#include "watchdog.h"
#include <baseinfo/ifconfig.h>
#include <sstream>
#include <utils/signals.h>
#include "chnmanager.h"

AcquisitionManager::AcquisitionManager(int index):
    m_pTimer(NULL),
    m_bConnected(FALSE),
    m_ilock(TRUE),
    m_iTime(-1),
    m_iMaxCycle(15),
    m_iIndex(index),
    m_quelock(TRUE) {
    addReference();
    m_pTimer = new Timer("acquisition",this);
}

AcquisitionManager::~AcquisitionManager()
{
    m_bConnected = FALSE;
    delete m_pTimer;
    dropReference();
}

MODULE_DEFINE_BEGIIN(AcquisitionManager)
if (ret) {
#ifndef LOCAL_TEST
    //开启采集
    if (m_iIndex == 0)
        startAcquire();
    m_pTimer->Start(1000,kPeriodic);
#else
    if (m_iIndex == 0)
        startAcquire();
    m_pTimer->Start(1000,kPeriodic);
#endif
}
else {
    m_pTimer->Stop();
    m_bConnected = FALSE;

    //停止采集
    if (m_iIndex == 0)
        stopAcquire();
}
MODULE_DEFINE_END

MODULE_NETWORK_BEGIN(AcquisitionManager)
if (isconected) {
    AutoLock autolock(m_quelock);
    m_events.push(3);
}
else {
    AutoLock autolock(m_quelock);
    m_events.push(4);
}
MODULE_NETWORK_END

void AcquisitionManager::RunTimer()
{
    m_iTime++;
    do {
        AutoLock autolock(m_quelock);
        if (!m_events.empty()) {
            m_iTime = 0;
            int evt = m_events.front();
            m_events.pop();
            LOG_DEBUG("handle event %d",evt);
            AutoUnlock unlock(m_quelock);
            if (evt == 0) {
                ChnManager::instance()->Start();
            }
            else if (evt == 2) {
                ChnManager::instance()->Stop();
            }
            else if (evt == 3) {
                {
                    AutoLock lock(m_ilock);
                    m_bConnected = true;
                }
                RegisterAcquisitor(m_iMaxCycle);
            }
            else if (evt == 4) {
                AutoLock lock(m_ilock);
                SetMsgStatus(DAS_REGISTERACQUISITOR,FALSE,m_iIndex);
                m_bConnected = FALSE;
            }
            return;
        }

    }while(0);

    if (m_iTime%m_iMaxCycle != 0)
        return;

    /*
     * 没有连接或者没有注册就到此为止
     */
    AutoLock autolock(m_ilock);
    if (!m_bConnected)
        return;

    if (!GetMsgStatus(DAS_REGISTERACQUISITOR,m_iIndex)) {
        return;
    }

//    if (m_iTime%(m_iMaxCycle) != 0)
//        return;
    m_iTime = 0;

    ChnManager::instance()->CommitData(m_iIndex);
}

BOOL AcquisitionManager::OnReceiveJson(
        S32 index,
        DAS_RESULT result,
        const string &method,
        const Json::Value &json)
{
    if (method == "registerAcquisitor") {
        if (result == DAS_SUCCESS) {
            if (json.isBool()) {
                m_ilock.Acquire();
                bool reg = json.asBool();
                SetMsgStatus(DAS_REGISTERACQUISITOR,reg,index);
                m_ilock.Release();
            }
            else {
                if (json.isObject() && json.isMember("valid") &&
                        json.isMember("date") &&
                        json.isMember("property")) {
                    m_ilock.Acquire();
                    bool valid = json["valid"].asBool();
                    SetMsgStatus(DAS_REGISTERACQUISITOR,valid,index);

                    m_ilock.Release();

                    if (valid) {
                        string date = json["date"].asString();
                        string script = "date -s '"+date+"'";

                        utils::MessageQueue msgQue;
                        msgQue.Execute(1,script);
                        msgQue.Execute(1,"hwclock -u -w");
                        if  (index != 0)
                        {
                       string property = json["property"].asString();
                       utils::WriteConfigFileStringValue(
                               "Config.ini","BASE","company",property);
                       SocketRequest().sendRequest("registerAgain",Json::Value());
                        }
                    }
                }
            }
            modifyCycle(true);
        }
        else {
            SetMsgStatus(DAS_REGISTERACQUISITOR,FALSE,index);
            modifyCycle(false);
            if (m_iMaxCycle >= 240) {
                m_iMaxCycle = 15;
                connectServer();
            }
            else {
                AutoLock autolock(m_quelock);
                m_events.push(3);
            }
//            SetMsgStatus(DAS_MSG_STATUS+m_iIndex,FALSE);
        }

        LOG_DEBUG("Register Acquisitor %s",
                  GetMsgStatus(DAS_REGISTERACQUISITOR,index)?"success":"failed");
    }
    return TRUE;
}

void AcquisitionManager::modifyCycle(bool ret)
{
    if (ret) {
        m_iMaxCycle /= 2;
        if (m_iMaxCycle<=15)
            m_iMaxCycle = 15;
    }
    else {
        m_iMaxCycle *= 2;
        if (m_iMaxCycle > 240) {
            m_iMaxCycle = 240;
        }
    }
}

DAS_RESULT AcquisitionManager::dailyMemory(Json::Value &result)
{
    result = ChnManager::instance()->DailyMemory();
    return DAS_SUCCESS;
}

void AcquisitionManager::RegisterAcquisitor(int timeout)
{
    Json::Value json;
    std::string strSecretkey,strId;
    if (m_iIndex == 0 &&
            utils::HasSection("Config.ini","GATEWAY")) {
        strId = utils::GetConfigFileStringValue("Config.ini","GATEWAY","id","");
        strSecretkey = utils::GetConfigFileStringValue("Config.ini","GATEWAY","secretkey","31cccf7264444398");
    }
    else {
        char center[10];
        sprintf(center,"CENTER%d",m_iIndex+1);
        strId = utils::GetConfigFileStringValue("Config.ini",center,"id","");
        strSecretkey = utils::GetConfigFileStringValue("Config.ini",center,"secretkey","31cccf7264444398");
    }
    json["gateway_id"] = strId;

    CMD5 md5;
    char md5buffer[MAX_ID_LEN+MAX_SECRETKEY_LEN];
    strcpy(md5buffer,strId.c_str());
    strcat(md5buffer,"{");
    strcpy(md5buffer,strSecretkey.c_str());
    strcat(md5buffer,"}");

    int len  = strId.length()+strSecretkey.length()+2;
    md5.GenerateMD5((unsigned char*)md5buffer,len);
    json["secrectkey"] = md5.ToString();
    json["version"] = DAS_VERSION;

    char ipaddr[MAX_NETADDR_LEN];
    char mask[MAX_NETADDR_LEN];
    GetIfAddr("eth0",ipaddr,mask);

    json["ipaddr"] = ipaddr;

    m_pRPCInterface->SendJsonRpc(
                this,"registerAcquisitor",
                json,timeout);
}

DAS_RESULT AcquisitionManager::connectServer()
{
//    string script;

//    script = getenv(CONFIG_DIR_ENV);
//    script +="/script/reset.sh";

//    SocketRequest().scriptRequest(script,1);
    m_pRPCInterface->TransportHandle()->ChangeStatus(false);
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::clearData()
{
//    AutoLock autolock(m_chnLock);
    ChnManager::instance()->ClearChannels();
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::startAcquire()
{
//    if (m_iIndex != 0)
//        return DAS_SUCCESS;
    AutoLock autolock(m_quelock);
//    sleep(2);
    m_events.push(0);
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::stopAcquire()
{
//    if (m_iIndex != 0)
//        return DAS_SUCCESS;
    AutoLock autolock(m_quelock);
//    while(!m_events.empty()){
//        m_events.pop();
//    }
    m_events.push(2);
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::getDeviceStatus(const Json::Value &params, Json::Value &result)
{
    if (params.isMember("id")) {
        S32 id = params["id"].asInt();
        tAcquisitor acquisitor;
        tConnection connector;
        GetAcquisitor(id,acquisitor,connector);

        if (!acquisitor.valid()) {
            Json::Value inner;
            inner["result"] = false;
            inner["status"] = false;
            result["inner"] = inner;
        }
        else {
            Json::Value inner;
            inner["result"] = acquisitor->acquireStatus();
            inner["status"] = acquisitor->powerStatus(connector);
            result["inner"] = inner;
        }
    }
    else {
//        AutoLock autolock(m_chnLock);
        vector<tChannel> &listChannel = ChnManager::instance()->AllChannels();
        for (vector<tChannel>::iterator iter = listChannel.begin();
             iter != listChannel.end();iter++) {
            tChannel chnnel = *iter;
            if (!chnnel.valid())
                continue;
            vector<tAcquisitor> list = chnnel->GetAllAcquisitors();
            for (vector<tAcquisitor>::iterator iter = list.begin();
                 iter != list.end();iter++) {
                tAcquisitor acquitor = *iter;
                if (!acquitor.valid())
                    continue;
                Json::Value dev;
                dev["id"] = acquitor->DevId();
                dev["status"] = acquitor->acquireStatus();
                result.append(dev);
            }
        }
    }
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::getTMCStatus(
        const Json::Value &params,
        Json::Value &result)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();

    devices dev(id);
    if (!dev.FetchItems())
        return DAS_DEVICENOTEXIST;
    deviceinfo_t devinfo = dev.getdevice();

    tConnection connector = m_pDevInterface->GetConnection(devinfo.trans);

    if (!connector.valid())
        return DAS_FAILDCONNECTION;

    tAcquisitor acquisitor = ChnManager::instance()->GetAcquisitor(devinfo);
    if (!acquisitor.valid())
        return DAS_INVALIDPARAMETER;
    U16 acqid[8] = {10501,10503,30504,30506,
                    10502,10530,10520,10514};
    string jstr[8] = {"power","gearPos","setTemp","houseTemp",
                 "workMode","valveStatus","timingSwitch",
                 "timingStatus"};
    int type[8] = {1,1,2,2,1,1,1,1};
    bool stat = true;
    for (int i = 0;i < 8;i++) {
        OpValue status;
        if (stat)
           status = acquisitor->
                indicateDevice(connector,acqid[i]);
        if (status.IsEmpty()) {
            result[jstr[i]] = 0xff;
            stat = false;
//            break;
        }
        else
            result[jstr[i]] = type[i]==0?((bool)(status.Integer()!=0)):
                                     (type[i]==1?status.Integer():status.Float());
    }

    //锁定模式
    do {
        OpValue status = acquisitor->indicateDevice(connector,10508);
        if (status.IsEmpty() || !status.IsInteger()) {
            result["lockMode"] = 0xff;
            stat = false;
            break;
        }
        if (status.Integer() == 0)
            result["lockMode"] = 1;
        else {
            OpValue statlock = acquisitor->indicateDevice(connector,10509);
            if (statlock.IsEmpty() || !statlock.IsInteger()) {
                result["lockMode"] = 0xff;
                stat = false;
                break;
            }
            if (statlock.Integer() == 1) {
                result["lockMode"] = 2;
            }
            else
                result["lockMode"] = 1;
        }
    }while(0);

    result["status"] = stat;
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::setTMCTimer(const Json::Value &params)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    int timerSwitch = params["timerSwitch"].asInt();

    OpValue opRet = acquisitor->indicateDevice(connector,"ctrl520",timerSwitch);
    if (!opRet.IsInteger())
        return DAS_FAILDSET;
    if (opRet.Integer() == 0)
        return DAS_NOTPASS;
    Json::Value timerJson = params["timer"];
    for (int i = 0;i < timerJson.size();i++) {
        Json::Value &timerParam = timerJson[i];
        S32 week = timerParam["week"].asInt();
        if (week < 1 || week > 7)
            return DAS_INVALIDPARAMETER;

        string dayBegin = timerParam["dayBegin"].asString();
        string dayEnd = timerParam["dayEnd"].asString();
        U16 begin = utils::strtimetobcd(dayBegin);
        U16 end = utils::strtimetobcd(dayEnd);

    //    string parm = utils::hexcmdtostr(&begin,2,'H')+' '+
    //            utils::hexcmdtostr(&end,2,'H');
        U32 tv = begin << 16;
        tv += end;
        OpValue optime = tv;
        OpValue timeSet = acquisitor->indicateDevice(
                    connector,20521+week-1,optime);
        bool ret = timeSet.Integer() == 1;
        if (!ret)
            return DAS_NOTPASS;
    }

    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::setTMCSwitch(const Json::Value &params)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    U8 swt = params["switch"].asInt();

    OpValue opRet = acquisitor->indicateDevice(connector,"ctrl530",swt);
    if (!opRet.IsInteger())
        return DAS_FAILDSET;
    return opRet.Integer()==1?DAS_SUCCESS:DAS_NOTPASS;
}

DAS_RESULT AcquisitionManager::setTMCTiming(const Json::Value &params)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    U8 swt = params["switch"].asInt();

    OpValue opRet = acquisitor->indicateDevice(connector,"ctrl514",swt);
    if (!opRet.IsInteger())
        return DAS_FAILDSET;
    return opRet.Integer()==1?DAS_SUCCESS:DAS_NOTPASS;
}

DAS_RESULT AcquisitionManager::setTMCGearPos(const Json::Value &params)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    U8 gearPos = params["gearPos"].asInt();

    OpValue opRet = acquisitor->indicateDevice(connector,"ctrl503",gearPos);
    if (!opRet.IsInteger())
        return DAS_FAILDSET;
    return opRet.Integer()==1?DAS_SUCCESS:DAS_NOTPASS;
}

DAS_RESULT AcquisitionManager::setTMCMode(const Json::Value &params)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    U8 mode = params["workMode"].asInt();

    OpValue opRet = acquisitor->indicateDevice(connector,"ctrl502",mode);
    if (!opRet.IsInteger())
        return DAS_FAILDSET;
    return opRet.Integer()==1?DAS_SUCCESS:DAS_NOTPASS;
}


/*
 * 半锁/全锁设置,但是解锁怎么办
 */
DAS_RESULT AcquisitionManager::setTMCLock(const Json::Value &params)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    U8 mode = params["lockMode"].asInt();

    if (mode < 0 || mode > 2)
        return DAS_FAILDSET;
    OpValue opRet;
    if (mode == 0) {
        opRet = acquisitor->indicateDevice(connector,"ctrl508",mode);
    }
    else {
        opRet = acquisitor->indicateDevice(connector,"ctrl508",1);
        if (!opRet.IsInteger() || opRet.Integer() == 0)
            return DAS_NOTPASS;
        if (mode == 1) {
            opRet = acquisitor->indicateDevice(connector,"ctrl509",0);
        }
        else
            opRet = acquisitor->indicateDevice(connector,"ctrl509",1);
    }

    if (!opRet.IsInteger())
        return DAS_FAILDSET;
    return opRet.Integer()==1?DAS_SUCCESS:DAS_NOTPASS;
}

DAS_RESULT AcquisitionManager::getIOStatus(
        const Json::Value &params,
        Json::Value &result)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    int type = params["type"].asInt();
    int idx = params["idx"].asInt();
    if (type == 1)
        return DAS_INVALIDPARAMETER;
    OpValue opRet = acquisitor->indicateDevice(connector,30801+idx);
    if (!opRet.IsInteger())
        result = 0;
    result = opRet.Integer();
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::setIOStatus(const Json::Value &params)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();
    tAcquisitor acquisitor;
    tConnection connector;
    DAS_RESULT ret;
    if ((ret = GetAcquisitor(id,acquisitor,connector)) != DAS_SUCCESS)
        return ret;
    int type = params["type"].asInt();
    int idx = params["idx"].asInt();
    int value = params["value"].asInt();
    if (type == 1)
        return DAS_INVALIDPARAMETER;

    OpValue opRet;
    if (value == 0)
        opRet = acquisitor->indicateDevice(connector,"ctrl831",idx);
    else
        opRet = acquisitor->indicateDevice(connector,"ctrl830",idx);
    if (!opRet.IsInteger())
        return DAS_FAILDSET;
    return opRet.Integer()==1?DAS_SUCCESS:DAS_NOTPASS;
}

DAS_RESULT AcquisitionManager::GetAcquisitor(S32 id, tAcquisitor &acquisitor, tConnection &connector)
{
    devices dev(id);
    if (!dev.FetchItems())
        return DAS_DEVICENOTEXIST;
    deviceinfo_t devinfo = dev.getdevice();

    connector = m_pDevInterface->GetConnection(devinfo.trans);

    if (!connector.valid())
        return DAS_FAILDCONNECTION;

    acquisitor = ChnManager::instance()->GetAcquisitor(devinfo);
    if (!acquisitor.valid())
        return DAS_INVALIDPARAMETER;
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::indicateDevice(
        S32 id, const string &acqId,
        const OpValue &params)
{
    devices dev(id);
    if (!dev.FetchItems())
        return DAS_DEVICENOTEXIST;
    deviceinfo_t devinfo = dev.getdevice();

    tConnection connector = m_pDevInterface->GetConnection(devinfo.trans);

    if (!connector.valid())
        return DAS_MEM_NOTALLOC;

    tAcquisitor acquisitor = ChnManager::instance()->GetAcquisitor(devinfo);
    if (!acquisitor.valid())
        return DAS_INVALIDPARAMETER;
    acquisitor->indicateDevice(connector,acqId,params);
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::updateDeviceList(
        const Json::Value &params,
        Json::Value& result)
{
    /*
     *  停止采集
     */
    AcqLock acqLock(this);
    DAS_RESULT dr = DAS_SUCCESS;
    Json::Value merror,deverror,transerror;
    /*
     *  更新型号
     */
    if (params.isMember("model")) {
        dr = updateTemplate(params["model"],merror,true);
    }

    /*
     *  更新型号
     */
    if (params.isMember("communication")) {
        dr = updateCommunication(params["communication"],transerror,true);
    }
    /*
     *  更新设备
     */
    if (params.isMember("device")) {
        //删除原来的数据
        devices sdev(-1);
        sdev.deletethis();
        dr = updateDevices(params["device"],deverror,true);
    }


    if (merror.empty() && deverror.empty() && transerror.empty()) {
        result["ret"] = true;
        return DAS_SUCCESS;
    }
    else {
        if (!merror.empty())
            result["modelError"] = merror;
        if (!deverror.empty())
            result["deviceError"] = deverror;
        if (!transerror.empty())
            result["communicationError"] = transerror;
        return DAS_STOREERROR;
    }
}

DAS_RESULT AcquisitionManager::updateTemplate(const Json::Value &params,Json::Value &result,bool lock)
{
    const Json::Value &jmodels = params;
    DAS_RESULT ret = DAS_SUCCESS;
    AcqLock acqLock(lock?NULL:this);

    for (int i = 0;i < jmodels.size();i++) {
        const Json::Value& jm = jmodels[i];

        S32 id = jm["id"].asInt();

        acquire acqm(id);
        acqm.deletethis();

        const Json::Value& jas = jm["acquire"];
        Json::Value acqerror;

        for ( int j = 0;j < jas.size();j++) {
            const Json::Value& ja = jas[j];
            S32 acqid = 0;
            string acqitem = ja["acqid"].asString();
            string dot;
            if (ja.isMember("dot"))
                dot = ja["dot"].asString();
            else
                dot = acqitem;//;
            string name = ja["name"].asString();
            S32 reglen = ja["reglen"].asInt();
            string acqparams;

            acqid = acquire::parseAcqId(acqitem);

            if (acqid == 0) {
                acqerror.append(acqitem);
                continue;
            }

            if (ja.isMember("parms")) {
                acqparams = ja["parms"].asString();
            }
            string expr = ja["expr"].asString();
            F32 rate = ja["rate"].asFloat();

            acquire acq(id,acqid);
            if (!acq.inorup(dot,name,reglen,acqparams,expr,rate))
                acqerror.append(acqitem);
        }

        string name = jm["name"].asString();
        string temp = jm["temp"].asString();

        models dm(id);
        if (!dm.inorup(temp) || !dm.updateName(name)) {
            Json::Value moderror;
            moderror["id"] = id;
            moderror["acqid"] = acqerror;
            result.append(moderror);
            ret = DAS_PARSEFAILED;
        }
        LOG_DEBUG("%d,model_id = %d",i,id);
    }
    return ret;
}

DAS_RESULT AcquisitionManager::updateCommunication(const Json::Value &params,Json::Value &result,bool lock)
{
    const Json::Value &jtransport = params;
    DAS_RESULT ret = DAS_SUCCESS;

    AcqLock acqLock(lock?NULL:this);

    transports alltrans(-1);
    alltrans.deletethis();

    for (int i = 0;i < jtransport.size();i++) {
        const Json::Value &jt = jtransport[i];
        S32 id = jt["id"].asInt();
        S32 delay = jt["delay"].asInt();
        S32 sample = jt["sample"].asInt();
        string strmode = jt["mode"].asString();
        const Json::Value &jaddr = jt["addr"];

        transports trans(id);
        int mode = (strmode == "serial")?TM_SEARIAL:(strmode == "tcp")?TM_TCP:TM_MAX;

        char addr[MAX_COND_LEN] = {0};

        if (mode == TM_SEARIAL)
            sprintf(addr,"%s:%d:%d:%d:%d",jaddr["chn"].asCString(),
                    jaddr["baudRate"].asInt(),
                    jaddr["dataBits"].asInt(),
                    jaddr["parity"].asInt(),
                    jaddr["stopBits"].asInt());
        else if(mode == TM_TCP)
            sprintf(addr,"%s:%d",jaddr["ip"].asCString(),jaddr["port"].asInt());

        if (!trans.inorup(sample,
                     time(NULL),
                     delay,
                     mode,
                     addr
                          )) {
            Json::Value err;
            err["id"] = id;
            result.append(err);
            ret = DAS_PARSEFAILED;
        }
    }
    return ret;
}

DAS_RESULT AcquisitionManager::updateDevices(const Json::Value &params,Json::Value &result, bool lock)
{
    const Json::Value &jdevices = params;
    DAS_RESULT ret = DAS_SUCCESS;
    Devices devs;
    AcqLock acqLock(lock?NULL:this);

    for (int i = 0;i < jdevices.size();i++) {
        const Json::Value &jsonDev = jdevices[i];
        S32 id = jsonDev["id"].asInt();
        DAS_RESULT dr = DAS_SUCCESS;

        if (jsonDev["opt"].asString() == "up") {
            dr = devs.addDevice(jsonDev);
        }
        else if (jsonDev["opt"].asString() == "del") {
            dr = devs.deleteDevice(jsonDev);
        }
        if (DAS_SUCCESS != dr) {
            Json::Value de;
            de["id"] = id;
            result.append(de);
            ret = DAS_PARSEFAILED;
        }

        LOG_DEBUG("%d,id = %d",i,id);
    }
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::debugDevice(
        const Json::Value &params,
        Json::Value &result)
{
    if (!params.isMember("communication"))
        return DAS_INVALIDADDR;
    Devices dev;
    transmgr_t tranmgr = dev.getCommunication(params["communication"]);
    tConnection connector = m_pDevInterface->GetConnection(tranmgr);

    if (!connector.valid())
        return DAS_MEM_NOTALLOC;
    if (params.isMember("template")) {
        Template temp;
        if (!temp.Parse(params["template"].asString()))
            return DAS_TEMPLATE_ERROR;
        ID_DEV devAddr = params["devId"].asCString();

        string stracq = params["acqid"].asString();
        S32 acqid = acquire::parseAcqId(stracq);

        acqid = acqid!=0?acqid:atoi(stracq.c_str());

        DebugItem item(devAddr,temp);
        item.SetItemId(acqid);
        item.SetDot(stracq);
        item.SetName(params["name"].asString());
        item.SetRegLength(params["reglen"].asInt());
        item.ParseDataExpr(params["expr"].asString(),params["rate"].asFloat());
        item.ParseParams(utils::Split(params["params"].asCString(),";"));

        OpValue csend = item.GenerateCmd();

        if (csend.IsEmpty()) {
            result["send"]=GetError(DAS_NOINFO);
            result["recv"]=GetError(DAS_INVALID);
            return DAS_SUCCESS;
        }

        Json::Value jsend;
        Json::Value jrecv;
        while (!csend.IsEmpty()) {
            U8 buffer[512];
            S32 byte = 0;

            CmdValue send = csend.GenCmd();

            jsend.append(utils::hexcmdtostr(send.Cmd(),send.Length()));
            if (!connector->AtomGetInstruction(tranmgr,send.Cmd(),send.Length(),buffer,byte)) {
                jrecv.append(GetError(DAS_TIMEOUT));
                result["send"] = jsend;
                result["recv"] = jrecv;
                return DAS_SUCCESS;
            }
            jrecv.append(utils::hexcmdtostr(buffer,byte));
            CmdValue recv(buffer,byte);
            item.ParseRecvCmd(recv);

            csend = item.GenerateNext();
        }
        result["send"] = jsend;
        result["recv"] = jrecv;
        OpValue data = item.Result();
        OpValue *next = &data;
        char jvalue[1024] = {0};
        while(next) {
            char buf[256] = {0};
            switch(next->type) {
            case TYPE_S8:
                sprintf(buf,"%d",next->data.s8);
                break;
            case TYPE_U8:
                sprintf(buf,"%u",next->data.u8);
                break;
            case TYPE_S16:
                sprintf(buf,"%d",next->data.s16);
                break;
            case TYPE_U16:
                sprintf(buf,"%u",next->data.u16);
                break;
            case TYPE_S32:
                sprintf(buf,"%d",next->data.s32);
                break;
            case TYPE_U32:
                sprintf(buf,"%u",next->data.u32);
                break;
            case TYPE_S64:
                sprintf(buf,"%lld",next->data.s64);
                break;
            case TYPE_U64:
                sprintf(buf,"%llu",next->data.u64);
                break;
            case TYPE_F32:
                sprintf(buf,"%.3f",next->data.f32);
                break;
            case TYPE_F64:
                sprintf(buf,"%.3f",next->data.f64);
                break;
            case TYPE_STR:
                strcpy(buf,next->data.str);
                break;
            case TYPE_CMD:
                strcpy(buf,
                       utils::hexcmdtostr(data.cmd.Cmd(),data.cmd.Length()).c_str());
                break;
            default:
                strcpy(buf,GetError(DAS_PARSEFAILED));
                break;
            }
            strcat(jvalue,buf);
            next = next->Next();
            if (next)
                strcat(jvalue,";");
        }

        result["value"] = jvalue;
        return DAS_SUCCESS;
    }
    else if(params.isMember("command")){
        U8 *cmd;
        S32 len;

        if ((len = utils::strtohexcmd(params["command"].asCString(),cmd)) == 0)
            return DAS_INVALIDPARAMETER;
        U8 buffer[256];
        S32 byte = 0;

        result["send"] = utils::hexcmdtostr(cmd,len);
        if (!connector->AtomGetInstruction(tranmgr,cmd,len,buffer,byte)) {
            free(cmd);
            result["recv"] = GetError(DAS_TIMEOUT);
            return DAS_SUCCESS;
        }
        free(cmd);
        result["recv"] = utils::hexcmdtostr(buffer,byte);
        return DAS_SUCCESS;
    }
    return DAS_INVALIDPARAMETER;
}

DAS_RESULT AcquisitionManager::indicateDevice(
        const Json::Value &params, Json::Value &result)
{
    if (!params.isMember("id"))
        return DAS_JSON_PARSEFAILD;
    S32 id = params["id"].asInt();

    devices dev(id);
    if (!dev.FetchItems())
        return DAS_DEVICENOTEXIST;
    deviceinfo_t devinfo = dev.getdevice();

    tConnection connector = m_pDevInterface->GetConnection(devinfo.trans);

    if (!connector.valid())
        return DAS_MEM_NOTALLOC;
    if (!params.isMember("acqid"))
        return DAS_INVALIDPARAMETER;

    string acqId = params["acqid"].asString();

    tAcquisitor acquisitor = ChnManager::instance()->GetAcquisitor(devinfo);
    if (!acquisitor.valid())
        return DAS_INVALIDPARAMETER;
    OpValue data;
    if (params.isMember("param")) {
        vector<OpValue> param = DataItem::ParseString(params["param"].asString());
        data = acquisitor->indicateDevice(connector,acqId,param);
    }
    else {
        result = params;
        data = acquisitor->indicateDevice(connector,acqId);
    }

    bool ret;
    if (!data.IsEmpty())
        ret = (bool)(data.Integer() != 0);
    else
        ret = false;
//    result["ret"]=true;
    if (result.isNull())
        result = ret;
    else
        result["ret"] = ret;
    return DAS_SUCCESS;
}

DAS_RESULT AcquisitionManager::setDevice(const Json::Value &params, Json::Value &result)
{
    return indicateDevice(params,result);
}





